<template>
  <div class="app-container">
    <!-- 搜索区域 -->
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
      <el-form-item label="设备ID" prop="deviceId">
        <el-input
          v-model="queryParams.deviceId"
          placeholder="请输入设备ID"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="设备名称" prop="deviceName">
        <el-input
          v-model="queryParams.deviceName"
          placeholder="请输入设备名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="设备状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择设备状态" clearable>
          <el-option label="离线" :value="0" />
          <el-option label="在线" :value="1" />
          <el-option label="故障" :value="2" />
        </el-select>
      </el-form-item>
      <el-form-item label="MAC地址" prop="macAddress">
        <el-input
          v-model="queryParams.macAddress"
          placeholder="请输入MAC地址"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 工具栏 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-refresh"
          size="mini"
          @click="handleQuery"
          v-hasPermi="['device:monitor:query']"
        >刷新</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-radio-group v-model="viewMode" size="mini" @change="handleViewModeChange">
          <el-radio-button label="card">卡片视图</el-radio-button>
          <el-radio-button label="list">列表视图</el-radio-button>
        </el-radio-group>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['device:monitor:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <!-- 卡片视图 -->
    <div v-if="viewMode === 'card'" class="device-cards">
      <el-row :gutter="16">
        <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="device in deviceList" :key="device.deviceId" class="card-col">
          <el-card class="device-card" :class="{'offline': device.status === 0}" shadow="hover">
            <div class="card-header">
              <div class="status-icon" :class="getStatusClass(device.status)">
                <i :class="getStatusIcon(device.status)"></i>
              </div>
              <div class="device-name">
                {{ device.deviceName }}
              </div>
            </div>
            
            <div class="card-body">
              <div class="device-info">
                <div class="info-item">
                  <i class="el-icon-wifi"></i>
                  <span>{{ device.wifiSsid || '未配置' }}</span>
                </div>
                <div class="info-item">
                  <i class="el-icon-location"></i>
                  <span>{{ device.locationName || '未知地址' }}</span>
                </div>
                <div class="info-item">
                  <i class="el-icon-monitor"></i>
                  <span>{{ device.deviceModel || 'N/A' }}</span>
                </div>
              </div>

              <div class="device-stats">
                <div class="stat-item">
                  <div class="stat-value">{{ device.onlineUsers || 0 }}</div>
                  <div class="stat-label">在线用户</div>
                </div>
                <div class="stat-item">
                  <div class="stat-value">{{ device.totalAuthToday || 0 }}</div>
                  <div class="stat-label">今日认证</div>
                </div>
                <div class="stat-item">
                  <div class="stat-value">{{ device.successRateToday || 0 }}%</div>
                  <div class="stat-label">成功率</div>
                </div>
              </div>
            </div>

            <div class="card-footer">
              <el-button
                type="primary"
                size="mini"
                @click="handleViewUsers(device)"
                v-hasPermi="['device:monitor:users']"
              >
                <i class="el-icon-user"></i> 查看用户
              </el-button>
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 分页 -->
      <pagination
        v-show="total>0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </div>

    <!-- 列表视图 -->
    <el-table v-if="viewMode === 'list'" v-loading="loading" :data="deviceList" @row-click="handleViewUsers">
      <el-table-column label="设备ID" align="center" prop="deviceId" width="150" />
      <el-table-column label="设备名称" align="center" prop="deviceName" width="150" />
      <el-table-column label="WiFi SSID" align="center" prop="wifiSsid" width="150" />
      <el-table-column label="设备状态" align="center" prop="status" width="100">
        <template slot-scope="scope">
          <el-tag :type="getStatusType(scope.row.status)">
            {{ getStatusText(scope.row.status) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="在线用户" align="center" prop="onlineUsers" width="100" sortable />
      <el-table-column label="今日认证" align="center" prop="totalAuthToday" width="100" sortable />
      <el-table-column label="成功率(%)" align="center" prop="successRateToday" width="100" sortable />
      <el-table-column label="地址" align="center" prop="locationName" show-overflow-tooltip />
      <el-table-column label="最后心跳" align="center" prop="lastHeartbeat" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.lastHeartbeat, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-user"
            @click.stop="handleViewUsers(scope.row)"
            v-hasPermi="['device:monitor:users']"
          >查看用户</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 列表视图分页 -->
    <pagination
      v-if="viewMode === 'list'"
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 侧边栏：用户列表 -->
    <el-drawer
      :title="'设备: ' + currentDevice.deviceName + ' - 用户列表'"
      :visible.sync="drawerVisible"
      direction="rtl"
      size="50%"
      :before-close="handleCloseDrawer"
    >
      <div class="drawer-content">
        <el-table v-loading="userLoading" :data="userList" height="calc(100vh - 100px)">
          <el-table-column label="MAC地址" align="center" prop="macAddress" width="150" />
          <el-table-column label="状态" align="center" prop="status" width="100">
            <template slot-scope="scope">
              <el-tag :type="scope.row.status === 0 ? 'success' : 'danger'">
                {{ scope.row.status === 0 ? '在线' : '离线' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="认证时间" align="center" prop="authTime" width="160">
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.authTime, '{y}-{m}-{d} {h}:{i}') }}</span>
            </template>
          </el-table-column>
          <el-table-column label="过期时间" align="center" prop="expireTime" width="160">
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.expireTime, '{y}-{m}-{d} {h}:{i}') }}</span>
            </template>
          </el-table-column>
          <el-table-column label="时长(分钟)" align="center" prop="onlineDuration" width="100">
            <template slot-scope="scope">
              <span>{{ Math.floor(scope.row.onlineDuration / 60) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="观看广告" align="center" prop="adWatched" width="100">
            <template slot-scope="scope">
              <el-tag :type="scope.row.adWatched === 1 ? 'success' : 'info'">
                {{ scope.row.adWatched === 1 ? '已观看' : '未观看' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="280" fixed="right">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                icon="el-icon-view"
                @click="handleUserDetail(scope.row)"
                v-hasPermi="['device:monitor:detail']"
              >详情</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-time"
                @click="handleExtendTime(scope.row)"
                v-hasPermi="['device:monitor:extend']"
                :disabled="scope.row.status !== 0"
              >延长</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-circle-close"
                @click="handleKickout(scope.row)"
                v-hasPermi="['device:monitor:kickout']"
                :disabled="scope.row.status !== 0"
              >踢出</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-warning"
                @click="handleBlacklist(scope.row)"
                v-hasPermi="['device:monitor:blacklist']"
              >拉黑</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-drawer>

    <!-- 延长时间对话框 -->
    <el-dialog title="延长上网时间" :visible.sync="extendDialogVisible" width="400px" append-to-body>
      <el-form :model="extendForm" :rules="extendRules" ref="extendForm" label-width="100px">
        <el-form-item label="延长时间" prop="extendMinutes">
          <el-input-number
            v-model="extendForm.extendMinutes"
            :min="5"
            :max="120"
            :step="5"
            label="分钟"
          ></el-input-number>
          <span style="margin-left: 10px;">分钟</span>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="extendDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitExtend">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 拉黑对话框 -->
    <el-dialog title="拉黑用户" :visible.sync="blacklistDialogVisible" width="500px" append-to-body>
      <el-form :model="blacklistForm" :rules="blacklistRules" ref="blacklistForm" label-width="100px">
        <el-form-item label="MAC地址">
          <el-input v-model="blacklistForm.macAddress" disabled></el-input>
        </el-form-item>
        <el-form-item label="拉黑原因" prop="reason">
          <el-input
            v-model="blacklistForm.reason"
            type="textarea"
            :rows="3"
            placeholder="请输入拉黑原因"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="blacklistDialogVisible = false">取 消</el-button>
        <el-button type="danger" @click="submitBlacklist">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 用户详情对话框 -->
    <el-dialog title="用户详情" :visible.sync="detailDialogVisible" width="600px" append-to-body>
      <el-descriptions :column="2" border v-if="currentUser">
        <el-descriptions-item label="MAC地址">{{ currentUser.macAddress }}</el-descriptions-item>
        <el-descriptions-item label="OpenID">{{ currentUser.openid || 'N/A' }}</el-descriptions-item>
        <el-descriptions-item label="认证状态">
          <el-tag :type="currentUser.status === 0 ? 'success' : 'danger'">
            {{ currentUser.status === 0 ? '已认证' : '未认证' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="广告状态">
          <el-tag :type="currentUser.adWatched === 1 ? 'success' : 'info'">
            {{ currentUser.adWatched === 1 ? '已观看' : '未观看' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="上网时长">{{ Math.floor(currentUser.onlineDuration / 60) }} 分钟</el-descriptions-item>
        <el-descriptions-item label="认证时间">{{ parseTime(currentUser.authTime) }}</el-descriptions-item>
        <el-descriptions-item label="过期时间">{{ parseTime(currentUser.expireTime) }}</el-descriptions-item>
        <el-descriptions-item label="最后活跃">{{ parseTime(currentUser.lastPollingTime) }}</el-descriptions-item>
        <el-descriptions-item label="创建时间" :span="2">{{ parseTime(currentUser.createTime) }}</el-descriptions-item>
        <el-descriptions-item label="备注" :span="2">{{ currentUser.remark || '无' }}</el-descriptions-item>
      </el-descriptions>
      <div slot="footer" class="dialog-footer">
        <el-button @click="detailDialogVisible = false">关 闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listDevices, listUsers, getUserDetail, kickoutUser, extendUserTime, blacklistUser } from "@/api/device/monitor";

export default {
  name: "DeviceMonitor",
  data() {
    return {
      // 遮罩层
      loading: true,
      userLoading: false,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 设备列表
      deviceList: [],
      // 用户列表
      userList: [],
      // 视图模式
      viewMode: 'card',
      // 抽屉显示
      drawerVisible: false,
      // 当前选中设备
      currentDevice: {},
      // 当前用户
      currentUser: null,
      // 对话框显示
      extendDialogVisible: false,
      blacklistDialogVisible: false,
      detailDialogVisible: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 12,
        deviceId: null,
        deviceName: null,
        status: null,
        macAddress: null
      },
      // 延长时间表单
      extendForm: {
        id: null,
        extendMinutes: 30
      },
      extendRules: {
        extendMinutes: [
          { required: true, message: "请输入延长时间", trigger: "blur" }
        ]
      },
      // 拉黑表单
      blacklistForm: {
        id: null,
        macAddress: null,
        reason: null
      },
      blacklistRules: {
        reason: [
          { required: true, message: "请输入拉黑原因", trigger: "blur" }
        ]
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询设备监控列表 */
    getList() {
      this.loading = true;
      listDevices(this.queryParams).then(response => {
        this.deviceList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    /** 切换视图模式 */
    handleViewModeChange() {
      if (this.viewMode === 'card') {
        this.queryParams.pageSize = 12;
      } else {
        this.queryParams.pageSize = 10;
      }
      this.handleQuery();
    },
    /** 查看用户列表 */
    handleViewUsers(row) {
      this.currentDevice = row;
      this.drawerVisible = true;
      this.userLoading = true;
      listUsers(row.deviceId).then(response => {
        this.userList = response.rows;
        this.userLoading = false;
      });
    },
    /** 关闭抽屉 */
    handleCloseDrawer() {
      this.drawerVisible = false;
      this.currentDevice = {};
      this.userList = [];
    },
    /** 用户详情 */
    handleUserDetail(row) {
      getUserDetail(row.id).then(response => {
        this.currentUser = response.data;
        this.detailDialogVisible = true;
      });
    },
    /** 延长时间 */
    handleExtendTime(row) {
      this.extendForm = {
        id: row.id,
        extendMinutes: 30
      };
      this.extendDialogVisible = true;
    },
    /** 提交延长时间 */
    submitExtend() {
      this.$refs["extendForm"].validate(valid => {
        if (valid) {
          extendUserTime(this.extendForm.id, this.extendForm.extendMinutes).then(response => {
            this.$modal.msgSuccess("延长成功");
            this.extendDialogVisible = false;
            this.handleViewUsers(this.currentDevice);
          });
        }
      });
    },
    /** 踢出用户 */
    handleKickout(row) {
      this.$modal.confirm('确认要踢出该用户吗？').then(() => {
        return kickoutUser(row.id);
      }).then(() => {
        this.handleViewUsers(this.currentDevice);
        this.$modal.msgSuccess("踢出成功");
      }).catch(() => {});
    },
    /** 拉黑用户 */
    handleBlacklist(row) {
      this.blacklistForm = {
        id: row.id,
        macAddress: row.macAddress,
        reason: null
      };
      this.blacklistDialogVisible = true;
    },
    /** 提交拉黑 */
    submitBlacklist() {
      this.$refs["blacklistForm"].validate(valid => {
        if (valid) {
          blacklistUser(this.blacklistForm.id, this.blacklistForm.reason).then(response => {
            this.$modal.msgSuccess("拉黑成功");
            this.blacklistDialogVisible = false;
            this.handleViewUsers(this.currentDevice);
          });
        }
      });
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('device/monitor/export', {
        ...this.queryParams
      }, `device_monitor_${new Date().getTime()}.xlsx`)
    },
    /** 获取状态图标 */
    getStatusIcon(status) {
      const icons = {
        0: 'el-icon-circle-close',
        1: 'el-icon-circle-check',
        2: 'el-icon-warning'
      };
      return icons[status] || 'el-icon-question';
    },
    /** 获取状态类名 */
    getStatusClass(status) {
      const classes = {
        0: 'status-offline',
        1: 'status-online',
        2: 'status-error'
      };
      return classes[status] || '';
    },
    /** 获取状态标签类型 */
    getStatusType(status) {
      const types = {
        0: 'info',
        1: 'success',
        2: 'warning'
      };
      return types[status] || 'info';
    },
    /** 获取状态文本 */
    getStatusText(status) {
      const texts = {
        0: '离线',
        1: '在线',
        2: '故障'
      };
      return texts[status] || '未知';
    }
  }
};
</script>

<style scoped>
.app-container {
  padding: 20px;
  overflow-x: hidden;
}

.device-cards {
  min-height: 400px;
  width: 100%;
}

.card-col {
  margin-bottom: 16px;
}

.device-card {
  transition: all 0.3s;
  height: 380px;
  width: 100%;
}

.device-card >>> .el-card__body {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 18px;
}

.device-card.offline {
  opacity: 0.7;
}

.device-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

.card-header {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid #ebeef5;
  height: 55px;
}

.status-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 10px;
  font-size: 20px;
  flex-shrink: 0;
}

.status-online {
  background: #67c23a;
  color: white;
}

.status-offline {
  background: #909399;
  color: white;
}

.status-error {
  background: #f56c6c;
  color: white;
}

.device-name {
  flex: 1;
  font-size: 15px;
  font-weight: bold;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.3;
  word-break: break-all;
  max-height: 39px;
}

.card-body {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.device-info {
  margin-bottom: 12px;
  height: 90px;
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 6px;
  color: #606266;
  font-size: 12px;
  line-height: 1.4;
  height: 24px;
}

.info-item i {
  margin-right: 6px;
  color: #909399;
  font-size: 13px;
  flex-shrink: 0;
  width: 16px;
}

.info-item span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.device-stats {
  display: flex;
  justify-content: space-around;
  padding: 10px 0;
  background: #f5f7fa;
  border-radius: 4px;
  height: 70px;
}

.stat-item {
  text-align: center;
  flex: 1;
}

.stat-value {
  font-size: 20px;
  font-weight: bold;
  color: #409eff;
  margin-bottom: 4px;
  line-height: 1;
}

.stat-label {
  font-size: 11px;
  color: #909399;
  white-space: nowrap;
}

.card-footer {
  text-align: center;
  padding-top: 12px;
  border-top: 1px solid #ebeef5;
  height: 52px;
  margin-top: auto;
}

.card-footer .el-button {
  width: 100%;
}

.drawer-content {
  padding: 0 20px;
}

/* 响应式优化 */
@media (max-width: 1920px) {
  .device-card {
    height: 360px;
  }
}

@media (max-width: 1200px) {
  .device-card {
    height: 340px;
  }
  
  .device-name {
    font-size: 14px;
  }
}

@media (max-width: 768px) {
  .device-card {
    height: auto;
    min-height: 320px;
  }
  
  .device-name {
    font-size: 14px;
  }
  
  .stat-value {
    font-size: 18px;
  }
  
  .stat-label {
    font-size: 10px;
  }
}
</style>

